#include <stdio.h>
#include <string.h>
#include "packet.h"

//GB3761_Header
void GB3761_Header::initHeader(void)
{
	header_Start = 0x68;
	header_Version1 = 2;
	header_Version2 = 2;
	header_Length1 = sizeof(GB3761_Common) + sizeof(PnFn);
	header_Length1 = sizeof(GB3761_Common) + sizeof(PnFn);
	header_Finish = 0x68;
}
void GB3761_Header::clearHeader(void)
{
	memset(header(), 0, sizeof(GB3761_Header));
}
void GB3761_Header::setLength(uint16_t l)
{
	header_Length1 = header_Version2 = l;
}
uint16_t GB3761_Header::getLength(void)const
{
	return header_Length1;
}
uint16_t GB3761_Header::getPacketLength(void)const
{
	return sizeof(GB3761_Header) + header_Length1 + 2;
}
bool GB3761_Header::checkHeader(void)const
{
	return header_Start		== 0x68
		&& header_Finish	== 0x68
		&& header_Version1	== 0x02 
		&& header_Version2	== 0x02 
		&& header_Length1	== header_Length2
		&& header_Length1	>=  sizeof(GB3761_Common) + sizeof(PnFn); 
}
uint8_t* GB3761_Header::header(void)
{
	return (uint8_t*)this;
}


//GB3761_Common
void GB3761_Common::initCommon(void)
{
	clearCommon();
}
void GB3761_Common::clearCommon(void)
{
	memset(common(), 0, sizeof(GB3761_Common));
}
bool GB3761_Common::checkCommon(void)const
{
	return true;
}
uint8_t* GB3761_Common::common(void)
{
	return (uint8_t*)this;
}


//PnFn
uint16_t PnFn::getPn(void)const
{
	uint16_t n = 0;

	switch(DA1)
	{
		case (1<<0): n = 1; break;
		case (1<<1): n = 2; break;
		case (1<<2): n = 3; break;
		case (1<<3): n = 4; break;
		case (1<<4): n = 5; break;
		case (1<<5): n = 6; break;
		case (1<<6): n = 7; break;
		case (1<<7): n = 8; break;
		case 0x00:   n = (DA2 == 0) ? 0x0000 : 0xEEEE;
		case 0xFF:   n = (DA2 == 0) ? 0xFFFF : 0xEEEE;
	}
	switch(n)
	{
		case 0x0000:
		case 0xEEEE:
		case 0xFFFF:
			return n;
	}
	if(DA2 < 1)
	{
		return 0xEEEE;
	}
	return ((DA2 - 1) * 8) + n;
}

uint8_t PnFn::getFn(void)const
{
	uint8_t n = 0;
	switch(DT1)
	{
		case (1<<0): n = 1; break;
		case (1<<1): n = 2; break;
		case (1<<2): n = 3; break;
		case (1<<3): n = 4; break;
		case (1<<4): n = 5; break;
		case (1<<5): n = 6; break;
		case (1<<6): n = 7; break;
		case (1<<7): n = 8; break;
		case 0: return (DT2 == 0) ? 0 : 0xEEEE;
	}
	if(DT2 > 30)
	{
		return 0xFF;
	}
	return (DT2 * 8) + n;
}
